#include "accountmanager.h"
#include "accountuser.h"
#include "accountloginrequest.h"
#include "accountloginresponse.h"
#include "accountgetfriendrequest.h"
#include "accountfriendresponse.h"
#include "accountfriend.h"
#include "network/networkmanager.h"
#include "imagedownload/avatarmanager.h"
#include "imagedownload/profilemanager.h"
#include "accountevent.h"
#include "accountprofilerequest.h"
#include "accountprofileresponse.h"
#include <account/accountloginner.h>

// Qt includes
#include <QDebug>


using namespace Account;

Manager *Manager::m_instance = NULL;

Manager *Manager::instance(QObject *parent)
{
    if (m_instance == NULL)
        m_instance = new Manager(parent);
    return m_instance;
}

Manager::Manager(QObject *parent) :
    QObject(parent),
    m_user(0),
    m_getFriendRequestPage(0),
    m_updateOnlineStatusTimer(0),
    m_onlineStatusRequest(0),
    m_recentContactRequest(0),
    m_enable(true)
{
    setConnection();
}

void Manager::setConnection() const
{
    // connect parse json websocket tra ve
    connect(Network::Manager::instance(), &Network::Manager::sessionKeyReady,
            this, &Manager::onSessionKeyReady);
    connect(Account::Loginner::instance(), &Account::Loginner::logouted,
            this, &Manager::onLogouted);
}


void Manager::unregisterParser(Parser *parser)
{
    m_parsers.removeAll(parser);
}


void Manager::init(const LoginResponse& loginResponse)
{
    m_enable = true;  // set lai

    if (m_user != NULL) {
        delete m_user;
        m_user = 0;
    }

    m_user = new User(loginResponse.userId(),
                      loginResponse.userName(),
                      loginResponse.displayName(),
                      loginResponse.avatar());

    // Download avatar of user
    ImageDownload::AvatarManager *avatarManager = ImageDownload::AvatarManager::instance();
    avatarManager->imageGet(loginResponse.avatar());

}

void Manager::onSessionKeyReady()
{
}

const Member *Manager::find(int id) const
{
    if (m_user->id() == id)
        return m_user;
    Finder::ConstIterator iterator = m_finder.find(id);
    if (iterator == m_finder.begin())
        return NULL;
    return *iterator;
}

Member *Manager::find(int id)
{
    if (m_user->id() == id)
        return m_user;
    return findFriend(id);
}

Friend *Manager::findFriend(int id)
{
    Finder::ConstIterator iterator = m_finder.find(id);
    if (iterator == m_finder.end())
        return NULL;
    return *iterator;
}

int Manager::getFriendIndex(int memberId) const
{
    if (m_user->id() == memberId)
        return -1;

    IndexFinder::ConstIterator iterator = m_indexFinder.find(memberId);
    if (iterator == m_indexFinder.end())
        return -2;

    return *iterator;
}

int Manager::friendCount() const
{
    return m_friends.count();
}


void Manager::onAvatarReady(const Member *member)
{
    emit avatarReady(member);
}

void Manager::Manager::deleteUser()
{
    delete m_user;
    m_user = 0;
}

void Manager::deleteBuddies()
{
    foreach (Friend *buddy, m_friends) {
        delete buddy;
    }
    m_friends.clear();
}

void Manager::deleteParsers()
{
    foreach (Parser *parser, m_parsers) {
        delete parser;
    }
    m_parsers.clear();
}

void Manager::clearIndexFinder()
{
    m_indexFinder.clear();
}

void Manager::clearBuddyFinder()
{
    m_finder.clear();
}

void Manager::clearData()
{
    clearIndexFinder();
    clearBuddyFinder();
    deleteParsers();
    deleteBuddies();
    deleteUser();
    m_getFriendRequestPage = 0;
    delete m_updateOnlineStatusTimer;
    m_updateOnlineStatusTimer = 0;
    m_enable = false;
    emit dataCleared();
}

void Manager::onLogouted()
{
    clearData();
}
